home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 July: Mac OS SDK / Dev.CD Jul 96 SDK / Dev.CD Jul 96 SDK1.toast / Development Kits (Disc 1) / OpenDoc / OpenDoc Development / Debugging Support / OpenDoc Source Code / Messaging / NamRslvr.cpp < prev    next >
Encoding:
Text File  |  1996-04-22  |  65.4 KB  |  2,178 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        NamRslvr.cpp
  3.  
  4.     Contains:    Implementation of Mac version of ODNameResolver class
  5.  
  6.     Owned by:    Nick Pilch
  7.  
  8.     Copyright:    © 1994 - 1996 by Apple Computer, Inc., all rights reserved.
  9.  
  10.     Change History (most recent first):
  11.  
  12.          <3>     3/14/96    NP        1290949, 1291292: Fix memory leaks with
  13.                                     whose and every clauses.
  14.          <2>     1/15/96    TJ        Cleaned Up
  15.         <73>     10/4/95    jpa        Added missing ODVolatiles [1285799]
  16.         <72>     10/3/95    TJ        Changes done by RefBall Team
  17.         <71>    25/09/95    NP        1979071: Check results of operator new.
  18.         <70>     9/11/95    NP        1272294: Messaging code cleanup. 1283174:
  19.                                     Mem leak plugs.
  20.         <69>      9/6/95    eeh        1282767: pass new context to
  21.                                     CallCountProcAux
  22.         <68>     8/29/95    jpa        DescPtr --> AEDesc* for Univ Hdrs 2.1.
  23.                                     [1279173]
  24.         <67>     8/26/95    TÇ        1274606 FB2: Patching Remarks
  25.         <66>     8/25/95    NP        1269331: Make a list of error descriptors
  26.                                     for Resolve.
  27.         <65>     8/23/95    NP        1276287: Move constant kODAppShell.
  28.         <64>     8/18/95    NP        1274946: Add kODErrNotAnODToken.
  29.         <63>     8/16/95    eeh        1276757: wrap SetUserODToken in TRY block
  30.         <62>     8/16/95    NP        1275241: IDL Review. Remove unnecessary
  31.                                     overrides. 1242421: Verify exception
  32.                                     handling in messaging.
  33.         <61>      8/7/95    NP        1195474: Resolve should be reentrant.
  34.         <60>      8/3/95    RR        #1257260: Collapse B classes. Remove
  35.                                     somInit methods. Don't call IsInitialized
  36.                                     or SubclassResponsibility
  37.         <59>     7/27/95    eeh        1204615: accept 'exmn' as well as 'null'
  38.         <58>     7/21/95    eeh        1266906: throw for
  39.                                     count==kODCountProcSwapValue
  40.         <57>     7/18/95    eeh        1262143: memory leaks
  41.         <56>      7/1/95    CC        Fix to NewODToken for crashing bug [for
  42.                                     Eric] (#1251894).
  43.         <55>     6/30/95    JP        Added FlushCacheContext
  44.         <54>     6/28/95    eeh        1262143: dispose AEDescs
  45.         <53>     6/27/95    NP        1262792: Call new version of OSLObjectInit
  46.         <52>     6/26/95    NP        1262143: Dispose copy of Apple event made
  47.                                     in CallEventHandler
  48.         <51>     6/23/95    NP        1195474: Make Resolve reentrant.
  49.         <50>     6/22/95    NP        1261275: Dispose artificially created
  50.                                     container tokens.
  51.         <49>     6/22/95    jpa        Fixed refcounting of SI by using TempODSI
  52.                                     objects. [1242642]
  53.         <48>     6/20/95    NP        1260387: Fix compare proc dispatching
  54.         <47>     6/20/95    JP        1251250: Changed ReleaseExtension into
  55.                                     Release
  56.         <46>     6/19/95    eeh        1246443: add PartFrameFromStandardPartToken
  57.                                     etc.
  58.         <45>     6/19/95    eeh        1259706: CallCountProc swallows errors
  59.         <44>     6/15/95    NP        1259581: Fix Memory leak.
  60.         <43>     6/13/95    eeh        1250399, 1254943, 1251194: fix how defaults
  61.                                     are called
  62.         <42>      6/7/95    eeh        1253097: plug leak in IsODToken; 1252761:
  63.                                     work in progress
  64.         <41>     5/26/95    RR        #1251403: Multithreading naming support
  65.         <40>     5/21/95    NP        1248898: GetUserToken, ODDescToAEDesc, etc.
  66.                                     recipe change. 1237955: Fix leak in
  67.                                     GetUserToken.
  68.         <39>      5/3/95    NP        1211084: Remove 5$. 1244237, 1244309: Fixes
  69.                                     for whose clauses.
  70.         <38>      5/1/95    NP        1244309: Fix whose clauses for embedded
  71.                                     parts.
  72.         <37>     4/27/95    NP        1244309-Rewrote implementation of
  73.                                     CallCountProc. Should be very close to
  74.                                     final now.
  75.         <36>     4/27/95    eeh        1230798: call part::ReleaseExtension on
  76.                                     semantic interfaces
  77.         <35>     4/25/95    DM        1172791: Replace AEHashTable with
  78.                                     OpenHashTable
  79.         <34>     4/25/95    NP        1186795, 1237220, 1240571: Fixed whose
  80.                                     clauses by allowing swapping in count proc.
  81.         <33>     4/14/95    NP        1186795: switch to embedded part for whose
  82.                                     clause. Half-assed implementation. 1239651:
  83.                                     Uninclude DfltAcs.h
  84.         <32>     3/24/95    eeh        1232249: remove GetContainingFrame
  85.         <31>     3/21/95    JP        1192027: Include ODRgstry & change some
  86.                                     constant names
  87.         <30>     3/20/95    NP        1225985: Change API of CreateSwapToken.
  88.         <29>     3/13/95    NP        1223764: CreateSwapToken should take an
  89.                                     ODFrame* parameter.
  90.         <28>      3/2/95    eeh        1214783: finish work on lists
  91.         <27>     2/22/95    eeh        1222904: fix use of SetCurrentContext
  92.         <26>     2/21/95    eeh        1214783: more default accessor stuff
  93.         <25>     2/15/95    NP        1220651: Allow failure from shell to be
  94.                                     handled by default accessors/handlers.
  95.         <24>     2/13/95    eeh        1214783: default token stuff
  96.         <23>      2/8/95    NP        1218550: Don't allocate OSLContexts
  97.                                     dynamically.
  98.         <22>      2/3/95    eeh        1217393: use new ODDesc etc
  99.         <21>     1/27/95    NP        1213948: New classes for ODDesc et al.
  100.         <20>     1/26/95    jpa        Include StdExts.xh [1206907]
  101.         <19>     1/25/95    eeh        1214783: changes to make default
  102.                                     accessors/handlers work
  103.         <18>     1/22/95    NP        GetUserToken, IsODToken, and
  104.                                     GetContextFromToken function signature
  105.                                     changes because of change to AE types.
  106.         <17>     1/16/95    eeh        1195186: add [G|S]etUserToken, IsODToken
  107.                                     and GetContextFromToken; remove
  108.                                     CreateTokenCommon;
  109.         <16>     1/11/95    NP        #1199991-Don't use ODPartWrapper.
  110.         <15>      1/9/95    NP        1194880: SemtIntf name changes.
  111.         <14>    12/23/94    JBS        1186869: hide ODPartWrapper from public
  112.                                     API; 1192557: ODPartWrapper realPart access
  113.         <13>    11/15/94    NP        1199847,1199991,1191053-Many changes.
  114.         <12>    10/10/94    NP        1192023-default accessors. 1186778-stuff
  115.                                     context behind the scenes. 1186795-count
  116.                                     proc should switch to embedded part when
  117.                                     needed.
  118.         <11>     9/29/94    RA        1189812: Mods for 68K build.
  119.         <10>     9/23/94    NP        1185851. Uncommented some callbacks so that
  120.                                     scripting is now really fully functional.
  121.          <9>     9/15/94    NP        1186778: Changed token handling code to
  122.                                     remove private info from token before
  123.                                     calling object accessor.
  124.          <8>      9/9/94    NP        1185674: don't blow up at uninit time.
  125.                                     1185851: implement scripting.
  126.          <7>      9/9/94    jpa        Don't delete fRootContext, to avoid crash.
  127.                                     Marked unimplemented methods for Nick to
  128.                                     fill in for a real fix. [1185674]
  129.          <6>     8/13/94    NP        1180819-Corresponding .cpp checkin for .idl
  130.                                     change. Added subclassresponsibility and
  131.                                     correct calls through to subclass.
  132.          <5>      8/3/94    NP        Cosmetic Object Master tweak.
  133.          <4>     7/13/94    NP        Implemented Get and SetCurrentContextPart.
  134.          <3>      7/5/94    NP        Started to fill in.
  135.          <2>      7/1/94    NP        Checked in fresher version.
  136.  
  137.     To Do:
  138.     In Progress:
  139. */
  140.  
  141. #ifndef SOM_ODPart_xh
  142. #include "Part.xh"
  143. #endif
  144.  
  145. #ifndef _ODDESUTL_
  146. #include <ODDesUtl.h>
  147. #endif
  148.  
  149. #ifndef _DFLTACS_
  150. #include <DfltAcs.h>
  151. #endif
  152.  
  153. #ifndef SOM_ODDesc_xh
  154. #include "ODDesc.xh"
  155. #endif
  156.  
  157. #ifndef SOM_ODOSLToken_xh
  158. #include "ODOSLTkn.xh"
  159. #endif
  160.  
  161. #ifndef SOM_ODObjectSpec_xh
  162. #include "ODObjSpc.xh"
  163. #endif
  164.  
  165. #ifndef _SEPRIV_
  166. #include "SEPriv.h"
  167. #endif
  168.  
  169. #ifndef _SEUTILS_
  170. #include "SEUtils.h"
  171. #endif
  172.  
  173. #ifndef SOM_ODMessageInterface_xh
  174. #include "MssgIntf.xh"
  175. #endif
  176.  
  177. #ifndef SOM_DefaultAccessorSI_xh
  178. #include "MssgSI.xh"
  179. #endif
  180.  
  181. #ifndef SOM_ODSession_xh
  182. #include "ODSessn.xh"
  183. #endif
  184.  
  185. #ifndef SOM_ODFrame_xh
  186. #include "Frame.xh"
  187. #endif
  188.  
  189. #ifndef SOM_ODPartWrapper_xh
  190. #include "PartWrap.xh"
  191. #endif
  192.  
  193. #ifndef SOM_ODSemanticInterface_xh
  194. #include "SemtIntB.xh"
  195. #endif
  196.  
  197. #ifndef _TEMPSI_
  198. #include "TempSI.h"
  199. #endif
  200.  
  201. #ifndef _OSLTOKEN_
  202. #include "OSLToken.h"
  203. #endif
  204.  
  205. #ifndef _CNTXTOSL_
  206. #include "CntxtOSL.h"
  207. #endif
  208.  
  209. #ifndef _EXCEPT_
  210. #include "Except.h"
  211. #endif
  212.  
  213. #ifndef _OPENHASH_
  214. #include "OpenHash.h"
  215. #endif
  216.  
  217. #ifndef _PLFMDEF_
  218. #include "PlfmDef.h"
  219. #endif
  220.  
  221. #ifndef _SIHLPABS_
  222. #include "SIHlpAbs.h"
  223. #endif
  224.  
  225. #ifndef _ODREGISTRY_
  226. #include "ODRgstry.xh"
  227. #endif
  228.  
  229. #ifndef _DFLTACS_
  230. #include "DfltAcs.h"
  231. #endif
  232.  
  233. #define VARIABLE_MACROS
  234. #define ODNameResolver_Class_Source
  235. #include <NamRslvr.xih>
  236.  
  237. #ifndef SOM_ODExtension_xh
  238. #include <Extensn.xh>
  239. #endif
  240.  
  241. #ifndef _ODDEBUG_
  242. #include "ODDebug.h"
  243. #endif
  244.  
  245. #ifndef _ODMEMORY_
  246. #include "ODMemory.h"
  247. #endif
  248.  
  249. #ifndef _ORDCOLL_
  250. #include "OrdColl.h"
  251. #endif
  252.  
  253. #ifndef SOM_Module_OpenDoc_StandardExtensions_defined
  254. #include "StdExts.xh"
  255. #endif
  256.  
  257. #ifndef SOM_Module_OpenDoc_StdDefs_defined
  258. #include <StdDefs.xh>
  259. #endif
  260.  
  261. #pragma segment ODNameResolver
  262.  
  263. #include "NamRslvB.cpp"    // Platform-independent methods, if any
  264.  
  265. //==============================================================================
  266. // Some implementation pointers.
  267. //==============================================================================
  268. /*
  269.  
  270. Format of an ODOSLToken:
  271.  
  272. -descriptorType: typeUserToken
  273.  
  274. -dataHandle is 12 bytes long. The first 8 bytes contain an ODDesc* and
  275. the second 8 bytes contain an embedded OSLContext.
  276.  
  277. */
  278. //==============================================================================
  279. // Constants
  280. //==============================================================================
  281.  
  282. const ODULong kNumPartsExpected = 20; // number of parts expected to be
  283.                                         //    involved in object spec resolution.
  284.  
  285. //==============================================================================
  286. // Function prototypes
  287. //==============================================================================
  288. #define OBJECTMASTERKLUDGE
  289. #ifdef OBJECTMASTERKLUDGE
  290. extern "C" { // functions may be called from a .c file
  291. #endif
  292. CallbackCallerProc ReturnCallbackFuncCaller(OSLCallbackSelector whichCallback);
  293.  
  294. ODStatic OSErr CallObjectAccessor(DescType        desiredClass,
  295.                                 const OSLToken*    containerToken,
  296.                                 DescType        containerClass,
  297.                                 DescType        keyForm,
  298.                                 const AEDesc*    keyData,
  299.                                 OSLToken*        value,
  300.                                 Boolean*        procFound,
  301.                                 long            contextRefCon);
  302.                                 
  303. ODStatic OSErr CallCountProc(DescType            desiredClass,
  304.                                 DescType        containerClass,
  305.                                 const OSLToken*    container,
  306.                                 long*            result,
  307.                                 long            contextRefCon);
  308.                                 
  309. ODStatic OSErr CallCompareProc(DescType            oper,
  310.                                 const AEDesc*    obj1,
  311.                                 const AEDesc*    obj2,
  312.                                 ODBoolean*        result,
  313.                                 long            contextRefCon);
  314.                                 
  315. ODStatic OSErr CallDisposeTokenProc(OSLToken*    unneededToken,
  316.                                     long        contextRefCon);
  317.  
  318. ODStatic OSErr CallMarkProc(const OSLToken*    dToken,
  319.                             const OSLToken*    markToken,
  320.                             long            index,
  321.                             long            contextRefCon);
  322.  
  323. ODStatic OSErr CallGetMarkTokenProc(const OSLToken*    dContainerToken,
  324.                                     DescType        containerClass,
  325.                                     OSLToken*        result,
  326.                                     long            contextRefCon);
  327.  
  328. ODStatic OSErr CallAdjustMarksProc(long                newStart,
  329.                                     long            newStop,
  330.                                     const OSLToken*    markToken,
  331.                                     long            contextRefCon);
  332.  
  333. ODStatic OSErr CallGetErrDescProc(AEDesc**    appDescPtr,
  334.                                     long    contextRefCon);
  335.  
  336. ODStatic long GetAppDoesFlags(long contextRefCon);
  337. #ifdef OBJECTMASTERKLUDGE
  338. }
  339. #endif
  340.  
  341. ODPart* PartFromContext(OSLContext* context);
  342. ODFrame* FrameFromContext(OSLContext* context);
  343. static ODBoolean TokenDefaultCanHandle( Environment* ev,
  344.         ODNameResolver* resolver, ODOSLToken* token );
  345. ODDesc* GetUserODToken(OSLToken* oslToken);
  346. void SetUserODToken(OSLToken* oslToken, ODDesc* odDesc);
  347. static void NewODToken( ODNameResolver* me, ODOSLToken* openDocToken,
  348.                          ODPart* part, ODFrame* frame, OSLToken* newToken);
  349.  
  350. //==============================================================================
  351. // SIContext
  352. //==============================================================================
  353.  
  354. class SIContext
  355. {
  356.   public:
  357.  
  358.     SIContext(Environment* ev, ODPart* part, ODFrame* frame,
  359.                 ODNameResolver* resolver,
  360.                 ODBoolean isDefaultToken = kODFalse);
  361.     ~SIContext();
  362.     
  363.     ODPart*             GetPart() {return fPart;}
  364.     ODFrame*             GetFrame() {return fFrame;}
  365.     ODNameResolver*        GetNameResolver() {return fNameResolver;}
  366.     ODBoolean             IsDefaultToken() {return fIsDefaultToken;}
  367.     void                 SetIsDefaultToken(ODBoolean isDefault)
  368.                                             {fIsDefaultToken = isDefault;}
  369.   private:
  370.     ODPart*            fPart;
  371.     ODFrame*        fFrame;
  372.     ODNameResolver*    fNameResolver;
  373.     ODBoolean        fIsDefaultToken;
  374. };
  375.  
  376. SIContext::SIContext(Environment* ev, ODPart* part, ODFrame* frame ,
  377.                 ODNameResolver* resolver,
  378.                 ODBoolean isDefaultToken)
  379. {
  380.     if (part)
  381.         part->Acquire(ev);
  382.     if (frame)
  383.         frame->Acquire(ev);
  384.     fPart = part;
  385.     fFrame = frame;
  386.     fNameResolver = resolver;
  387.     fIsDefaultToken = isDefaultToken;
  388.     
  389.     ASSERT_FRAME_MATCHES_PART( ev, frame, part );
  390. }
  391.  
  392. SIContext::~SIContext()
  393. {
  394.     Environment*    ev = somGetGlobalEnvironment();
  395.  
  396.     TRY
  397.         if (fPart)
  398.             fPart->Release(ev);
  399.         if (fFrame)
  400.             fFrame->Release(ev);
  401.     CATCH_ALL
  402.     ENDTRY
  403. }
  404.  
  405. //------------------------------------------------------------------------------
  406. // DeleteAContext
  407. //------------------------------------------------------------------------------
  408.  
  409. inline void DeleteAContext(OSLContext* context)
  410. {
  411.     delete (SIContext*)(context->refCon);
  412. #if ODDebug
  413.     context->refCon = 0x50FF8001;
  414. #endif
  415. //    delete context;
  416. }
  417.  
  418. //------------------------------------------------------------------------------
  419. // PartFromContext
  420. //------------------------------------------------------------------------------
  421.  
  422. ODPart* PartFromContext(OSLContext* context)
  423. {
  424.     return ((SIContext*)(context->refCon))->GetPart();
  425. }
  426.  
  427. //------------------------------------------------------------------------------
  428. // FrameFromContext
  429. //------------------------------------------------------------------------------
  430.  
  431. ODFrame* FrameFromContext(OSLContext* context)
  432. {
  433.     return ((SIContext*)(context->refCon))->GetFrame();
  434. }
  435.  
  436. //------------------------------------------------------------------------------
  437. // SIContextFromOSLToken
  438. //
  439. //    Return pointer to SIContext that is referenced from this OSLToken.
  440. //------------------------------------------------------------------------------
  441.  
  442. static SIContext* SIContextFromOSLToken(ODNameResolver* resolver,
  443.                                         const OSLToken* token)
  444. {
  445.     WASSERT(token->dataHandle != kODNULL);
  446.     OSLContext context;
  447.     OSLGetTokenContext(token, &context);
  448.     return (SIContext*)(context.refCon);
  449. }
  450.  
  451. //------------------------------------------------------------------------------
  452. // SIContextFromToken
  453. //
  454. //    Return pointer to SIContext that is referenced from this ODOSLToken.
  455. //------------------------------------------------------------------------------
  456.  
  457. static SIContext* SIContextFromToken(ODNameResolver* resolver,
  458.                                         ODOSLToken* token)
  459. {
  460.     AEDesc    tokenAsAEDesc;
  461.     SIContext*    retVal;
  462.  
  463.     WASSERT(token != kODNULL);
  464.     THROW_IF_ERROR(ODDescToAEDesc(token, &tokenAsAEDesc));
  465.     WASSERT(tokenAsAEDesc.dataHandle != kODNULL);
  466.     retVal = SIContextFromOSLToken(resolver, &tokenAsAEDesc);
  467.     AEDisposeDesc(&tokenAsAEDesc);
  468.     return retVal;
  469. }
  470.  
  471. //------------------------------------------------------------------------------
  472. // SetIsDefaultToken
  473. //------------------------------------------------------------------------------
  474.  
  475. static void SetIsDefaultToken(ODNameResolver* resolver,
  476.                                 ODOSLToken* token, ODBoolean isDefaultToken)
  477. {
  478.     WASSERT(token != kODNULL);
  479.     SIContext* sic = SIContextFromToken(resolver, token);
  480.     WASSERT(sic != kODNULL);
  481.     sic->SetIsDefaultToken(isDefaultToken);
  482. }
  483.  
  484. //------------------------------------------------------------------------------
  485. // MakeNULLToken
  486. //------------------------------------------------------------------------------
  487.  
  488. inline static void MakeNULLToken( OSLToken *theToken )
  489. {
  490.     theToken->descriptorType = typeNull ;
  491.     theToken->dataHandle = NULL ;
  492. }
  493.     
  494. //==============================================================================
  495. // SIContextTableKey
  496. //==============================================================================
  497.  
  498. struct SIContextTableKey
  499. {
  500.     ODPart*        fPart;
  501.     ODFrame*    fFrame;
  502.     SIContextTableKey(ODPart* part, ODFrame* frame) {fPart = part;
  503.                                                         fFrame = frame;}
  504. };
  505.  
  506. //==============================================================================
  507. // ODNameResolver
  508. //==============================================================================
  509.  
  510. //------------------------------------------------------------------------------
  511. // ODNameResolver::somInit
  512. //------------------------------------------------------------------------------
  513.  
  514. //------------------------------------------------------------------------------
  515. // ODNameResolver::InitNameResolver
  516. //------------------------------------------------------------------------------
  517.  
  518. SOM_Scope void  SOMLINK ODNameResolverInitNameResolver(ODNameResolver *somSelf, Environment *ev,
  519.         ODSession* session)
  520. {
  521.     ODNameResolverData *somThis = ODNameResolverGetData(somSelf);
  522.     ODNameResolverMethodDebug("ODNameResolver","ODNameResolverInitNameResolver");
  523.  
  524.     SOM_CATCH
  525.         return;
  526.  
  527.     /* Moved from somInit. SOM itself sets fields to zero
  528.     _fRootContext.getCallerProc = kODNULL;
  529.     _fRootContext.refCon = 0;
  530.     _fCurrentlyResolving = 0;
  531.     _fSession = kODNULL;
  532.     _fContextTable = kODNULL;
  533.     _fCurrentContextPart = kODNULL;
  534.     _fHashTableRefCount = 0;
  535.     */
  536.     
  537.     somSelf->InitObject(ev);
  538.  
  539.     _fSession = session;
  540.  
  541.     const ODUShort        kODOSLContextSize = sizeof(OSLContext);
  542.     const ODBoolean        kNotInSystemHeap = kODFalse;
  543.     ODFrame* const        kNoFrameInfo = kODNULL;
  544.  
  545.     somSelf->CreateContext(ev, kODAppShell, kNoFrameInfo, &_fRootContext);
  546.     THROW_IF_ERROR(OSLObjectInit(&_fRootContext));
  547.     THROW_IF_NULL(_fContextTable = new OpenHashTable(OpenHashTable::EqualTwoLongs, OpenHashTable::HashTwoLongs) );
  548.     _fContextTable->Initialize(kNumPartsExpected, sizeof(SIContextTableKey),
  549.                                 kODOSLContextSize);
  550.     _fCurrentContextPart = new OrderedCollection;
  551.     somSelf->AddNewContextPartToTopOfStack(ev, (ODPart*)kODAppShell);
  552. //    _fCurrentContextPart = kODAppShell;
  553.     _fErrDescList = new OrderedCollection;
  554. }
  555.  
  556. //------------------------------------------------------------------------------
  557. // ODNameResolver::somUninit
  558. //------------------------------------------------------------------------------
  559.  
  560. SOM_Scope void  SOMLINK ODNameResolversomUninit(ODNameResolver *somSelf)
  561. {
  562.     ODNameResolverData *somThis = ODNameResolverGetData(somSelf);
  563.     ODNameResolverMethodDebug("ODNameResolver","somUninit");
  564.  
  565.     TRY
  566.         // somSelf->FlushContextCache(somGetGlobalEnvironment());
  567.         // It is incorrect to call methods on somSelf inside somUninit, 
  568.         // a subclass may have already been somUninited.  See OpenDoc Building Code for details.
  569.         // Instead the implementation of FlushContextCache has been copied here.
  570.         
  571.         if (_fContextTable)
  572.         {
  573.             // BEGIN copy of FlushContextCache implementation
  574.             OSLContext                value;
  575.             OpenHashTableIterator   i(_fContextTable);
  576.             
  577.             if (_fHashTableRefCount == 0)
  578.                 for (i.First((void*) 0, &value); i.IsNotComplete(); i.Next((void*) 0, &value))
  579.                 {
  580.                     DeleteAContext(&value);
  581.                     i.RemoveCurrent();
  582.                 }
  583.             // END copy of FlushContextCache implementation
  584.         }
  585.         
  586.     CATCH_ALL
  587.     ENDTRY
  588.         
  589.     DeleteAContext(&_fRootContext);
  590.     ODDeleteObject(_fContextTable);
  591.     ODDeleteObject(_fCurrentContextPart);
  592.     ODDeleteObject(_fErrDescList);
  593. }
  594. #if 0
  595. //------------------------------------------------------------------------------
  596. // ODNameResolver::Purge
  597. //------------------------------------------------------------------------------
  598.  
  599. SOM_Scope ODSize  SOMLINK ODNameResolverPurge(ODNameResolver *somSelf, Environment *ev,
  600.         ODSize size)
  601. {
  602. //    ODNameResolverData *somThis = ODNameResolverGetData(somSelf);
  603.     ODNameResolverMethodDebug("ODNameResolver","ODNameResolverPurge");
  604.  
  605.     ODUnused(size);
  606.     return 0;
  607. }
  608. #endif /* 0 */
  609. //------------------------------------------------------------------------------
  610. // ODNameResolver::AddErrDescToList
  611. //------------------------------------------------------------------------------
  612.  
  613. struct ErrorDescRec
  614. {
  615.     AEDesc    aeDesc;
  616.     ODDesc*    odDesc;
  617. };
  618.  
  619. SOM_Scope AEDesc*  SOMLINK ODNameResolverAddErrDescToList(ODNameResolver *somSelf, Environment *ev,
  620.         ODDesc* odDesc)
  621. {
  622.     ODNameResolverData *somThis = ODNameResolverGetData(somSelf);
  623.     ODNameResolverMethodDebug("ODNameResolver","AddErrDescToList");
  624.  
  625.     ErrorDescRec*    descRec = new ErrorDescRec;
  626.     descRec->odDesc = odDesc;
  627.     THROW_IF_ERROR(ODDescToAEDesc(odDesc, &descRec->aeDesc));
  628.     _fErrDescList->AddFirst(descRec);
  629.     return &descRec->aeDesc;
  630. }
  631.  
  632. //------------------------------------------------------------------------------
  633. // ODNameResolver::Resolve
  634. //------------------------------------------------------------------------------
  635.  
  636. // FOR CallGetErrDescProc. WE REALLY SHOULD BE KEEPING A LIST OF THESE FOR EVERY
  637. //    PART. OSL WILL WRITE INTO THE DESCRIPTOR IF IT IS A NULL DESCRIPTOR.
  638. //    IF AN APP RETURNS A NON-NULL DESCRIPTOR, THEN THE OSL WILL NOT WRITE INTO
  639. //    IT (ASSUMING THAT IT WAS A PREVIOUSLY WRITTEN-INTO ONE?
  640.  
  641. SOM_Scope void  SOMLINK ODNameResolverResolve(ODNameResolver *somSelf, Environment *ev,
  642.         ODObjectSpec* theObject, ODOSLToken* token, ODPart* contextPart)
  643. {
  644.     ODNameResolverData *somThis = ODNameResolverGetData(somSelf);
  645.     ODNameResolverMethodDebug("ODNameResolver","Resolve");
  646.  
  647.     OSLContext        context;
  648.     OSErr            error;
  649.     ODFrame* const    kNoFrameInfo = kODNULL;
  650.     ODBoolean        contextPartStackChanged = kODFalse;
  651.  
  652.     SOM_TRY
  653.         somSelf->AddNewContextPartToTopOfStack(ev, contextPart);
  654.         contextPartStackChanged = kODTrue;
  655.  
  656.         ODSemanticInterface* theSI = somSelf->AcquireSemtIntf(ev, contextPart);
  657.         if (!theSI)
  658.             THROW(errAENoSuchObject);
  659.         else if (contextPart != kODAppShell)
  660.             theSI->Release(ev);
  661.  
  662.         somSelf->GetContextForPart(ev, contextPart, kNoFrameInfo, &context);
  663.     
  664.         AEDesc objectSpecifier;
  665.         THROW_IF_ERROR( ODDescToAEDesc( theObject, &objectSpecifier ) );
  666.     
  667. #ifdef TESTING_EXMN
  668.         // replace the null desc at the root of containment with 'exmn'
  669.         (void)Munger( objectSpecifier.dataHandle, 0, "null", 4, "exmn", 4 );
  670. #endif
  671.  
  672.         AEDesc realToken = NULL_DESCRIPTOR_DEFINITION;
  673.     
  674.         ++_fCurrentlyResolving;
  675.         error = OSLResolve(&objectSpecifier, &realToken, &context);
  676.         --_fCurrentlyResolving;
  677.     
  678.         AEDisposeDesc(&objectSpecifier);
  679.         if (error == noErr)
  680.             error = AEDescToODDesc( &realToken, token );
  681.         AEDisposeDesc(&realToken);
  682.         
  683.         somSelf->DeleteTopOfContextPartStack(ev);
  684.  
  685.         THROW_IF_ERROR (error);
  686.     SOM_CATCH_ALL
  687.         if (contextPartStackChanged)
  688.             somSelf->DeleteTopOfContextPartStack(ev);
  689.     SOM_ENDTRY
  690.  
  691.     TRY
  692.         OrderedCollectionIterator    iter(_fErrDescList);
  693.         ErrorDescRec*                element;
  694.     
  695.         for (element = (ErrorDescRec*)iter.First();
  696.                 iter.IsNotComplete();
  697.                 element = (ErrorDescRec*)iter.Next())
  698.         {
  699.             AEDescToODDesc(&element->aeDesc, element->odDesc);
  700.             AEDisposeDesc(&element->aeDesc);
  701.         }
  702.         _fErrDescList->DeleteAll();
  703.     CATCH_ALL
  704.         _fErrDescList->DeleteAll();
  705.     ENDTRY
  706. }
  707.  
  708. //------------------------------------------------------------------------------
  709. // ODNameResolver::AcquireSemtIntf
  710. //
  711. //    Convenience function. Returns the SemanticInterface object associated with
  712. //    an ODPart object or kODNULL if none exists.
  713. //------------------------------------------------------------------------------
  714.  
  715. SOM_Scope ODSemanticInterface*  SOMLINK ODNameResolverAcquireSemtIntf(ODNameResolver *somSelf, Environment *ev,
  716.         ODPart* part)
  717. {
  718.     ODNameResolverData *somThis = ODNameResolverGetData(somSelf);
  719.     ODNameResolverMethodDebug("ODNameResolver","AcquireSemtIntf");
  720.  
  721.     ODSemanticInterface*    theSI;
  722.  
  723.     if (part == kODAppShell)
  724.         theSI = _fSession->AcquireShellSemtInterface(ev);
  725.     else
  726.     {
  727.         if (part->HasExtension(ev, kODExtSemanticInterface))
  728.             theSI = (ODSemanticInterface*)part->AcquireExtension(ev, 
  729.                                                         kODExtSemanticInterface);
  730.         else
  731.             theSI = kODNULL;
  732.     }
  733.  
  734.     return theSI;
  735. }
  736.  
  737. //------------------------------------------------------------------------------
  738. // ODNameResolver::GetSession
  739. //
  740. //    Convenience function. Returns the SemanticInterface object associated with
  741. //    an ODPart object or kODNULL if none exists.
  742. //------------------------------------------------------------------------------
  743.  
  744. SOM_Scope ODSession*  SOMLINK ODNameResolverGetSession(ODNameResolver *somSelf, Environment *ev)
  745. {
  746.     ODNameResolverData *somThis = ODNameResolverGetData(somSelf);
  747.     ODNameResolverMethodDebug("ODNameResolver","GetSession");
  748.     
  749.     return _fSession;
  750. }
  751.  
  752. //------------------------------------------------------------------------------
  753. // ODNameResolver::GetPartFromToken
  754. //------------------------------------------------------------------------------
  755.  
  756. SOM_Scope ODPart*  SOMLINK ODNameResolverGetPartFromToken(ODNameResolver *somSelf, Environment *ev,
  757.         OSLToken* token)
  758. {
  759. //    ODNameResolverData *somThis = ODNameResolverGetData(somSelf);
  760.     ODNameResolverMethodDebug("ODNameResolver","ODNameResolverGetPartFromToken");
  761.  
  762.     OSLContext    context;
  763.     ODPart*        part;
  764.  
  765.     if (OSErr error = OSLGetTokenContext(token, &context))
  766.     {
  767.         part = kODNULL;
  768.         ODSetSOMException(ev, error);
  769.     }
  770.     else
  771.         part = PartFromContext(&context);
  772.     
  773.     ASSERT_FRAME_MATCHES_PART( ev, FrameFromContext(&context), part );
  774.     return part;
  775. }
  776.  
  777. //------------------------------------------------------------------------------
  778. // ODNameResolver::AddNewContextPartToTopOfStack
  779. //------------------------------------------------------------------------------
  780.  
  781. SOM_Scope void  SOMLINK ODNameResolverAddNewContextPartToTopOfStack(ODNameResolver *somSelf, Environment *ev,
  782.         ODPart* contextPart)
  783. {
  784.     ODNameResolverData *somThis = ODNameResolverGetData(somSelf);
  785.     ODNameResolverMethodDebug("ODNameResolver","AddNewContextPartToTopOfStack");
  786.  
  787.     _fCurrentContextPart->AddFirst(contextPart);
  788. }
  789.  
  790. //------------------------------------------------------------------------------
  791. // ODNameResolver::DeleteTopOfContextPartStack
  792. //------------------------------------------------------------------------------
  793.  
  794. SOM_Scope void  SOMLINK ODNameResolverDeleteTopOfContextPartStack(ODNameResolver *somSelf, Environment *ev)
  795. {
  796.     ODNameResolverData *somThis = ODNameResolverGetData(somSelf);
  797.     ODNameResolverMethodDebug("ODNameResolver","DeleteTopOfContextPartStack");
  798.  
  799.     _fCurrentContextPart->RemoveFirst();
  800. }
  801.  
  802. //------------------------------------------------------------------------------
  803. // ODNameResolver::GetCurrentContextPart
  804. //------------------------------------------------------------------------------
  805.  
  806. SOM_Scope ODPart*  SOMLINK ODNameResolverGetCurrentContextPart(ODNameResolver *somSelf, Environment *ev)
  807. {
  808.     ODNameResolverData *somThis = ODNameResolverGetData(somSelf);
  809.     ODNameResolverMethodDebug("ODNameResolver","ODNameResolverGetCurrentContextPart");
  810.  
  811.     OSLContext    curContext;
  812.  
  813.     // IF WE'RE IN THE OSL, THE OSL IS DETERMINING THE CONTEXT. OTHERWISE, WE
  814.     //    KEEP THAT STATE.
  815.     if (_fCurrentlyResolving)
  816.     {
  817.         THROW_IF_ERROR(GetCurrentContext(&curContext));
  818.         return PartFromContext(&curContext);
  819.     }
  820.     else
  821. //        return _fCurrentContextPart;
  822.         return (ODPart*)_fCurrentContextPart->First();
  823. }
  824.  
  825. //------------------------------------------------------------------------------
  826. // ODNameResolver::SetCurrentContextPart
  827. //------------------------------------------------------------------------------
  828.  
  829. SOM_Scope void  SOMLINK ODNameResolverSetCurrentContextPart(ODNameResolver *somSelf, Environment *ev,
  830.         ODPart* part)
  831. {
  832.     ODNameResolverData *somThis = ODNameResolverGetData(somSelf);
  833.     ODNameResolverMethodDebug("ODNameResolver","ODNameResolverSetCurrentContextPart");
  834.  
  835.     // DON'T ALLOW SETTING INTERNAL OSL STATE.
  836.     ASSERTM(!_fCurrentlyResolving, kODErrUndefined, "ODNameResolver: SetCurrentContextPart: Unexpected State.");
  837.     // $$$$$ NEED TO DO REFCOUNTING HERE
  838.     _fCurrentContextPart->RemoveFirst();
  839.     _fCurrentContextPart->AddFirst(part);
  840. //    _fCurrentContextPart = part;
  841. }
  842.  
  843. //------------------------------------------------------------------------------
  844. // ODNameResolver::GetContextForPart
  845. //------------------------------------------------------------------------------
  846.  
  847. SOM_Scope void  SOMLINK ODNameResolverGetContextForPart(ODNameResolver *somSelf, Environment *ev,
  848.         ODPart* part,
  849.         ODFrame* frame,
  850.         OSLContext* context)
  851. {
  852.     ODNameResolverData *somThis = ODNameResolverGetData(somSelf);
  853.     ODNameResolverMethodDebug("ODNameResolver","ODNameResolverGetContextForPart");
  854.  
  855.     SOM_CATCH
  856.         return;
  857.  
  858.     OSLContext            localContext;
  859.     SIContextTableKey    key(part, frame);
  860.  
  861. //    if (frame)
  862.     ASSERT_FRAME_MATCHES_PART( ev, frame, part );
  863.  
  864.     if (part == kODAppShell)
  865.         *context = _fRootContext;
  866.     else if (_fContextTable->GetValue(&key, context))
  867.         ;
  868.     else
  869.     {
  870.         somSelf->CreateContext(ev, part, frame, &localContext);
  871.         _fContextTable->ReplaceEntry(&key, &localContext);
  872.         *context = localContext;
  873.     }
  874. }
  875.  
  876. //------------------------------------------------------------------------------
  877. // ODNameResolver::CreateContext
  878. //------------------------------------------------------------------------------
  879.  
  880. SOM_Scope void  SOMLINK ODNameResolverCreateContext(ODNameResolver *somSelf, Environment *ev,
  881.         ODPart* part,
  882.         ODFrame* frame,
  883.         OSLContext* context)
  884. {
  885. //    ODNameResolverData *somThis = ODNameResolverGetData(somSelf);
  886.     ODNameResolverMethodDebug("ODNameResolver","ODNameResolverCreateContext");
  887.  
  888.     SOM_CATCH
  889.         return;
  890.  
  891.     SIContext*    siContext;
  892.  
  893.     context->getCallerProc = ReturnCallbackFuncCaller;
  894.  
  895.     ASSERT_FRAME_MATCHES_PART( ev, frame, part );
  896.     siContext = new SIContext(ev, part, frame, somSelf);
  897.  
  898.     context->refCon = (long)siContext;
  899. }
  900.  
  901. //------------------------------------------------------------------------------
  902. // ODNameResolver::FlushContextCache
  903. //------------------------------------------------------------------------------
  904.  
  905. SOM_Scope void  SOMLINK ODNameResolverFlushContextCache(ODNameResolver *somSelf, Environment *ev)
  906. {
  907.     ODNameResolverData *somThis = ODNameResolverGetData(somSelf);
  908.     ODNameResolverMethodDebug("ODNameResolver","FlushContextCache");
  909.  
  910.     OSLContext                value;
  911.     OpenHashTableIterator   i(_fContextTable);
  912.     
  913.     if (_fHashTableRefCount == 0)
  914.         for (i.First((void*) 0, &value); i.IsNotComplete(); i.Next((void*) 0, &value))
  915.         {
  916.             DeleteAContext(&value);
  917.             i.RemoveCurrent();
  918.         }
  919. }
  920.  
  921. //------------------------------------------------------------------------------
  922. // ODNameResolver::NeedContextCache
  923. //------------------------------------------------------------------------------
  924.  
  925. SOM_Scope void  SOMLINK ODNameResolverNeedContextCache(ODNameResolver *somSelf, Environment *ev,
  926.         ODBoolean lockIt)
  927. {
  928.     ODNameResolverData *somThis = ODNameResolverGetData(somSelf);
  929.     ODNameResolverMethodDebug("ODNameResolver","NeedContextCache");
  930.  
  931.     if (lockIt) {
  932.         WASSERT(_fHashTableRefCount >= 0);
  933.         ++_fHashTableRefCount;
  934.     }
  935.     else {
  936.         --_fHashTableRefCount;
  937.         WASSERT(_fHashTableRefCount >= 0);
  938.     }
  939. }
  940.  
  941. //------------------------------------------------------------------------------
  942. // ODNameResolver::TokenIsDefault
  943. //------------------------------------------------------------------------------
  944. SOM_Scope ODBoolean  SOMLINK ODNameResolverTokenIsDefault(ODNameResolver *somSelf, Environment *ev,
  945.         AEDesc* token )
  946. {
  947.     ODNameResolverData *somThis = ODNameResolverGetData(somSelf);
  948.     ODNameResolverMethodDebug("ODNameResolver","ODNameResolverTokenIsDefault");
  949.  
  950.     WASSERT( token->descriptorType == typeUserToken );
  951.     return SIContextFromOSLToken(somSelf, token)->IsDefaultToken();
  952. }
  953.  
  954. //------------------------------------------------------------------------------
  955. // GetUserODToken
  956. //
  957. //    Get the "user" token from the token that the OSL passes around.
  958. //
  959. //    The userToken is the first four bytes.
  960. //------------------------------------------------------------------------------
  961.  
  962. ODDesc* GetUserODToken(OSLToken* oslToken)
  963. {
  964.     return *((ODDesc**)(*(oslToken->dataHandle)));
  965. }
  966.  
  967. //------------------------------------------------------------------------------
  968. // ODNameResolver::GetUserToken
  969. //
  970. //    Optimization: Don't have make OD token into AEDesc. We know the format of
  971. //    an OSLToken exactly. The ODDesc* will be in the first four bytes of the
  972. //    data.
  973. //------------------------------------------------------------------------------
  974.  
  975. SOM_Scope ODDesc*  SOMLINK ODNameResolverGetUserToken(ODNameResolver *somSelf, Environment *ev,
  976.         ODOSLToken* token)
  977. {
  978. //    ODNameResolverData *somThis = ODNameResolverGetData(somSelf);
  979.     ODNameResolverMethodDebug("ODNameResolver","ODNameResolverGetUserToken");
  980.  
  981.     ODDesc*    retVal = kODNULL;
  982.  
  983.     SOM_TRY
  984.         AEDesc    tokenAsAEDesc;
  985.  
  986.         if ( token->GetDescType(ev) != typeUserToken)
  987.             THROW( kODErrNotAnODToken );
  988.  
  989.         THROW_IF_ERROR(ODDescToAEDesc(token, &tokenAsAEDesc));
  990.         retVal = GetUserODToken(&tokenAsAEDesc);
  991.         AEDisposeDesc(&tokenAsAEDesc);
  992. #if 0
  993.         AEDesc tokenAsAEDesc;
  994.         THROW_IF_ERROR( ODDescToAEDesc( token, &tokenAsAEDesc ) );
  995.         if ( tokenAsAEDesc.descriptorType != typeUserToken)
  996. //            THROW( kODErrInvalidParameter );
  997.     
  998.         if ( tokenAsAEDesc.dataHandle == kODNULL)
  999. //            THROW( kODErrInvalidParameter );
  1000.     
  1001.         AEDesc* userAEDesc = new AEDesc;
  1002.         // EXTRACT USER TOKEN FROM DATAHANDLE.
  1003.         *userAEDesc = *((AEDesc*)(*(tokenAsAEDesc.dataHandle)));
  1004.         AEDesc    tempAEDesc;
  1005.         AEDuplicateDesc(userAEDesc, &tempAEDesc);
  1006.     
  1007.         ODDesc* userToken = new ODDesc();
  1008.         THROW_IF_NULL(userToken);
  1009.         userToken->InitODDesc(ev);
  1010.     
  1011.         THROW_IF_ERROR( AEDescToODDesc(userAEDesc, userToken ) );
  1012.         userToken->SetHadToAllocate(ev);
  1013.     
  1014.         *desc = userToken;
  1015. #endif /* 0 */
  1016.     SOM_CATCH_ALL
  1017.     SOM_ENDTRY
  1018.     
  1019.     return retVal;
  1020. }
  1021.  
  1022. //------------------------------------------------------------------------------
  1023. // ODNameResolver::IsODToken
  1024. //------------------------------------------------------------------------------
  1025.  
  1026. SOM_Scope ODBoolean  SOMLINK ODNameResolverIsODToken(ODNameResolver *somSelf, Environment *ev,
  1027.         ODOSLToken* token)
  1028. {
  1029. //    ODNameResolverData *somThis = ODNameResolverGetData(somSelf);
  1030.     ODNameResolverMethodDebug("ODNameResolver","ODNameResolverIsODToken");
  1031.     WASSERT( token );
  1032.     return token->GetDescType(ev) == typeUserToken;
  1033. }
  1034.  
  1035. //------------------------------------------------------------------------------
  1036. // ODNameResolver::GetContextFromToken
  1037. //------------------------------------------------------------------------------
  1038.  
  1039. SOM_Scope void  SOMLINK ODNameResolverGetContextFromToken(ODNameResolver *somSelf, Environment *ev,
  1040.         ODOSLToken* token,
  1041.         ODPart** part,
  1042.         ODFrame** frame)
  1043. {
  1044. //    ODNameResolverData *somThis = ODNameResolverGetData(somSelf);
  1045.     ODNameResolverMethodDebug("ODNameResolver","ODNameResolverGetContextFromToken");
  1046.     
  1047.     WASSERT(part);
  1048.     WASSERT(frame);
  1049.  
  1050.     SOM_TRY
  1051.         AEDesc realToken;
  1052.         THROW_IF_ERROR( ODDescToAEDesc( token, &realToken ) );
  1053.     
  1054.         WASSERT( realToken.descriptorType == typeUserToken );
  1055.         *part = kODNULL;
  1056.         *frame = kODNULL;
  1057.         
  1058.         // $$$$$This is really really really gross!  Why the hell can't we define
  1059.         // a struct so we don't have to blindly grop around inside the handle?
  1060.         //    I agree-NP-it will be done.
  1061.     
  1062.         OSLContext context = *(OSLContext*)
  1063.                 ((*(realToken.dataHandle))+sizeof(ODDesc*));
  1064.         (void)AEDisposeDesc( &realToken );
  1065.         *part = PartFromContext(&context);
  1066.         *frame = FrameFromContext(&context);
  1067.         ASSERT_FRAME_MATCHES_PART( ev, *frame, *part );
  1068.     SOM_CATCH_ALL
  1069.     SOM_ENDTRY
  1070. }
  1071.  
  1072. //------------------------------------------------------------------------------
  1073. // ODNameResolver::CreateSwapToken
  1074. //------------------------------------------------------------------------------
  1075.  
  1076. SOM_Scope void  SOMLINK ODNameResolverCreateSwapToken(ODNameResolver *somSelf, Environment *ev,
  1077.         ODOSLToken* token,
  1078.         ODPart* part,
  1079.         ODFrame* frame)
  1080. {
  1081.     ODNameResolverData *somThis = ODNameResolverGetData(somSelf);
  1082.     ODNameResolverMethodDebug("ODNameResolver","ODNameResolverCreateSwapToken");
  1083.  
  1084.     SOM_CATCH
  1085.         return;
  1086.  
  1087. //    if (frame)
  1088.     ASSERT_FRAME_MATCHES_PART( ev, frame, part );
  1089.     
  1090.     OSLToken localToken ;
  1091.     THROW_IF_ERROR( ODDescToAEDesc( token, &localToken ) );
  1092.  
  1093.     OSLSetTokenDescType(&localToken, kSwitchDescType);
  1094.  
  1095.     OSLContext                context;
  1096.  
  1097.     somSelf->GetContextForPart(ev, part, frame, &context);
  1098.     OSLSetTokenContext(&localToken, &context);
  1099.  
  1100.     THROW_IF_ERROR( AEDescToODDesc( &localToken, token ) );
  1101.     (void)AEDisposeDesc( &localToken );
  1102. }
  1103.  
  1104. //------------------------------------------------------------------------------
  1105. // ODNameResolver::CallObjectAccessor
  1106. //------------------------------------------------------------------------------
  1107.  
  1108. SOM_Scope void  SOMLINK ODNameResolverCallObjectAccessor(ODNameResolver *somSelf, Environment *ev,
  1109.         ODPart* part,
  1110.         ODDescType desiredClass,
  1111.         ODOSLToken* containerToken,
  1112.         ODDescType containerClass,
  1113.         ODDescType keyForm,
  1114.         ODDesc* keyData,
  1115.         ODOSLToken* token)
  1116. {
  1117.     ODNameResolverData *somThis = ODNameResolverGetData(somSelf);
  1118.     ODNameResolverMethodDebug("ODNameResolver","ODNameResolverCallObjectAccessor");
  1119.  
  1120.     SOM_CATCH
  1121.         return;
  1122.  
  1123.     OSLContext    curContext;
  1124.  
  1125.     // CHECK THAT CURRENT CONTEXT IS THE SAME AS CONTEXT FOR thePart
  1126.     if (part != somSelf->GetCurrentContextPart(ev))
  1127.         THROW(errAEAccessorNotFound);
  1128.  
  1129.     THROW_IF_ERROR(GetCurrentContext(&curContext));
  1130.  
  1131. //    Don't bother putting anything *in* realToken since it'll just get
  1132. //    overwritten later (by NewODToken)
  1133.     AEDesc realToken = NULL_DESCRIPTOR_DEFINITION;
  1134. #define FIX_ODNAMERESOLVERCALLOBJECTACCESSOR_LEAK 0
  1135. #if FIX_ODNAMERESOLVERCALLOBJECTACCESSOR_LEAK
  1136. //    THIS IS SILLY. WE NEED TO REDESIGN NewODToken SO IT'S SMARTER ABOUT THIS.
  1137.     somSelf->DisposeToken(ev, token);
  1138.     token = new ODOSLToken();
  1139.     token->InitODOSLToken(ev);
  1140. #endif
  1141.     AEDesc realContainer;
  1142.     THROW_IF_ERROR( ODDescToAEDesc( containerToken, &realContainer ) );
  1143.  
  1144.     AEDesc realData;
  1145.     THROW_IF_ERROR( ODDescToAEDesc( keyData, &realData ) );
  1146.  
  1147.     THROW_IF_ERROR(OSLCallObjectAccessor(desiredClass,
  1148.                                         &realContainer,
  1149.                                         containerClass,
  1150.                                         keyForm,
  1151.                                         &realData,
  1152.                                         &realToken));
  1153.     (void)AEDisposeDesc( &realContainer );
  1154.     (void)AEDisposeDesc( &realData );
  1155.  
  1156.     THROW_IF_ERROR( AEDescToODDesc(&realToken, token ) );
  1157.     (void)AEDisposeDesc( &realToken );
  1158.  
  1159.     THROW_IF_ERROR(SetCurrentContext(&curContext));
  1160. }
  1161.  
  1162. //------------------------------------------------------------------------------
  1163. // ODNameResolver::DisposeToken
  1164. //------------------------------------------------------------------------------
  1165.  
  1166. SOM_Scope void  SOMLINK ODNameResolverDisposeToken(ODNameResolver *somSelf, Environment *ev,
  1167.         ODOSLToken* theToken)
  1168. {
  1169. //    ODNameResolverData *somThis = ODNameResolverGetData(somSelf);
  1170.     ODNameResolverMethodDebug("ODNameResolver","ODNameResolverDisposeToken");
  1171.  
  1172.     SOM_TRY
  1173.         // don't assert this: it could be a list too
  1174. //        WASSERT(somSelf->IsODToken(ev, theToken));
  1175.     
  1176.         OSLToken localToken;
  1177.         THROW_IF_ERROR( ODDescToAEDesc( theToken, &localToken ) );
  1178.         // NEED TO DELETE THE OBJECT HERE BECAUSE ONLY localToken GETS PASSED
  1179.         //    BACK INTO OUR CODE FROM THE OSL.
  1180.         ODDeleteObject(theToken);
  1181.         THROW_IF_ERROR(OSLDisposeToken(&localToken));
  1182.     SOM_CATCH_ALL
  1183.     SOM_ENDTRY
  1184. }
  1185.  
  1186. //------------------------------------------------------------------------------
  1187. // ReturnCallbackFuncCaller
  1188. //------------------------------------------------------------------------------
  1189.  
  1190. CallbackCallerProc ReturnCallbackFuncCaller(OSLCallbackSelector whichCallback)
  1191. {
  1192.     CallbackCallerProc    result;
  1193.  
  1194.     switch(whichCallback)
  1195.     {
  1196.         case kObjectAccessor:
  1197.             result = (CallbackCallerProc)CallObjectAccessor;
  1198.             break;
  1199.         case kCallbackFlagsGetter:
  1200.             result = (CallbackCallerProc)GetAppDoesFlags;
  1201.             break;
  1202.         case kCountProc:
  1203.             result = (CallbackCallerProc)CallCountProc;
  1204.             break;
  1205.         case kCompareProc:
  1206.             result = (CallbackCallerProc)CallCompareProc;
  1207.             break;
  1208.         case kDisposeTokenProc:
  1209.             result = (CallbackCallerProc)CallDisposeTokenProc;
  1210.             break;
  1211.         case kGetMarkTokenProc:
  1212.             result = (CallbackCallerProc)CallGetMarkTokenProc;
  1213.             break;
  1214.         case kMarkProc:
  1215.             result = (CallbackCallerProc)CallMarkProc;
  1216.             break;
  1217.         case kAdjustMarksProc:
  1218.             result = (CallbackCallerProc)CallAdjustMarksProc;
  1219.             break;
  1220.         case kGetErrDescProc:
  1221.             result = (CallbackCallerProc)CallGetErrDescProc;
  1222.             break;
  1223.         default:
  1224.             ASSERTM(false, 0, "NamRslvr.ReturnCallbackFuncCaller: Reached default case in switch.");
  1225.             break;
  1226.     }
  1227.  
  1228.     return result;
  1229. }
  1230.  
  1231. //------------------------------------------------------------------------------
  1232. // GetSI
  1233. //
  1234. //    Given a context refCon, find the ODSemanticInterface object and the ODPart
  1235. //    object corresponding. If they can't be found, return kODFalse; return
  1236. //    kODTrue otherwise.
  1237. //------------------------------------------------------------------------------
  1238.  
  1239. static ODSemanticInterface* GetSI(long contextRefCon, ODPart** thePart)
  1240. {
  1241.     ODNameResolver*    nameResolver
  1242.             = ((SIContext*)contextRefCon)->GetNameResolver();
  1243.     
  1244.     *thePart = ((SIContext*)contextRefCon)->GetPart();
  1245.     return nameResolver->AcquireSemtIntf(somGetGlobalEnvironment(),*thePart);
  1246. }
  1247.  
  1248. //------------------------------------------------------------------------------
  1249. // CreateNewODOSLToken
  1250. //
  1251. //    This function shares a lot of code with NewODToken. Let's consolidate!
  1252. //    -NP 6/21/95
  1253. //
  1254. //    Create an "OpenDoc token", one with context information and an embedded
  1255. //    ODDesc* for a user token.
  1256. //------------------------------------------------------------------------------
  1257.  
  1258. SOM_Scope void  SOMLINK ODNameResolverCreateNewODOSLToken(ODNameResolver *somSelf, Environment *ev,
  1259.         AEDesc* odOSLToken,
  1260.         ODDesc* userToken,
  1261.         ODPart* part,
  1262.         ODFrame* frame)
  1263. {
  1264.     OSLContext    context;
  1265.  
  1266.     somSelf->GetContextForPart(ev, part, frame, &context);
  1267.     odOSLToken->descriptorType = typeUserToken;
  1268.     odOSLToken->dataHandle = (Handle)ODNewHandle(sizeof(ODDesc*)
  1269.                                 + sizeof(OSLContext));
  1270.     OSLSetTokenContext(odOSLToken, &context);
  1271.     SetUserODToken(odOSLToken, userToken);
  1272. }
  1273.  
  1274. //------------------------------------------------------------------------------
  1275. // NewODToken
  1276. //
  1277. //    Takes the already allocated newToken and openDocToken and sets up an OpenDoc
  1278. //    style token.
  1279. //    Places a null descriptor in openDocToken as the "user token"
  1280. //------------------------------------------------------------------------------
  1281.  
  1282. static void NewODToken( ODNameResolver* me, ODOSLToken* openDocToken,
  1283.                          ODPart* part, ODFrame* frame, OSLToken* newToken )
  1284. {
  1285.     Environment*    ev = somGetGlobalEnvironment();
  1286.     OSLContext        context;
  1287.  
  1288.     WASSERT(openDocToken);
  1289.  
  1290.     // CHECK TO SEE IF THIS IS A NULL TOKEN
  1291.     DescType dt = openDocToken->GetDescType(ev);
  1292. //    ODBoolean okToOverwrite = (dt == 'dead') || (dt == typeNull);
  1293.     ODBoolean okToOverwrite = (dt == typeNull);
  1294.  
  1295. //    if (dt != 'dead' && dt != typeNull && dt != typeAEList &&
  1296. //            dt != typeObjectBeingExamined)
  1297.     if (dt != typeNull && dt != typeAEList && dt != typeObjectBeingExamined)
  1298.         WARN("Some unknown descriptor type in NewODToken.");
  1299.  
  1300.     // MUST SAVE OFF ORIGINAL OSLToken FOR CERTAIN TOKENS.
  1301.     AEDesc savedToken;
  1302.     if ( !okToOverwrite )
  1303.         // what's there now MATTERS; save it for wrapping
  1304.         savedToken = *newToken;
  1305.     else
  1306.         MakeNULLDesc(&savedToken);
  1307.  
  1308.     // INITIALIZE OSLToken TO THE RIGHT THING.
  1309.     newToken->descriptorType = typeUserToken;
  1310.     // $$$$$ THIS KNOWLEDGE OF HOW BIG THE STRUCTURE IS SHOULD BE ENCAPSULATED
  1311.     //    SOMEWHERE ELSE!!!!
  1312.     Handle h = (Handle)ODNewHandle(sizeof(ODDesc*) + sizeof(OSLContext));
  1313.     newToken->dataHandle = h;
  1314.     // GET AN OSLContext FOR THIS PART.
  1315.     me->GetContextForPart(ev, part, frame, &context);
  1316.     OSLSetTokenContext(newToken, &context);
  1317.  
  1318.     // CREATE USER TOKEN AND STICK IT IN THE OSLToken.
  1319.     ODDesc* tmpToken = new ODDesc();
  1320.     THROW_IF_NULL(tmpToken);
  1321.     tmpToken->InitODDesc(ev);
  1322.     THROW_IF_ERROR( AEDescToODDesc( &savedToken, tmpToken ) );
  1323.     SetUserODToken(newToken, tmpToken);
  1324.  
  1325.     // FINALLY INITIALIZE openDocToken AS WELL
  1326.     THROW_IF_ERROR( AEDescToODDesc(newToken, openDocToken ) );
  1327. }
  1328.  
  1329. //------------------------------------------------------------------------------
  1330. // CopyContextIntoToken
  1331. //
  1332. //    Move 2nd 8 bytes of dataHandle from one token to the other.
  1333. //    Should use OSLGetTokenContext and OSLSetTokenContext instead.
  1334. //------------------------------------------------------------------------------
  1335.  
  1336. static void CopyContextIntoToken(const OSLToken* sourceToken,
  1337.                                     OSLToken* destToken)
  1338. {
  1339.     OSLContext    context = GETBYTESOFHANDLE(sourceToken->dataHandle, OSLContext,
  1340.                                             sizeof(AEDesc));
  1341.  
  1342.     SETBYTESOFHANDLE(destToken->dataHandle, OSLContext, context,
  1343.                         sizeof(AEDesc));
  1344. }
  1345.  
  1346. //------------------------------------------------------------------------------
  1347. // TokenDefaultCanHandle
  1348. //------------------------------------------------------------------------------
  1349.  
  1350. static ODBoolean TokenDefaultCanHandle( Environment* ev,
  1351.         ODNameResolver* resolver, ODOSLToken* token )
  1352. {
  1353.     ODBoolean result = kODFalse;
  1354.     AEDesc realToken;
  1355.     THROW_IF_ERROR( ODDescToAEDesc( token, &realToken ) );
  1356.     switch ( realToken.descriptorType )
  1357.     {
  1358.         case typeUserToken:
  1359.             if ( !resolver->TokenIsDefault(ev, &realToken) )
  1360.             {
  1361.                 ODDesc* userToken;
  1362.                 userToken = resolver->GetUserToken( ev, token );
  1363.                 AEDesc realUserToken;
  1364.                 THROW_IF_ERROR( ODDescToAEDesc( userToken, &realUserToken ) );
  1365.  
  1366.                 ODBoolean isStandardToken =
  1367.                         CanBeStandardPartToken( &realUserToken )
  1368.                         || realUserToken.descriptorType == typeNull
  1369.                         || realUserToken.descriptorType == typeObjectBeingExamined;
  1370.  
  1371.                 AEDisposeDesc(&realUserToken);
  1372.  
  1373.                 result = isStandardToken;
  1374.             }
  1375.             else
  1376.                 result = kODTrue;
  1377.             break;
  1378.         case typeNull:
  1379.             result = kODTrue;
  1380.             break;
  1381.     }
  1382.     (void)AEDisposeDesc( &realToken );
  1383.     return result;
  1384. }
  1385.  
  1386. //------------------------------------------------------------------------------
  1387. // GetCallObjectAccessor
  1388. //
  1389. //    Used for compile-time type checking only.
  1390. //------------------------------------------------------------------------------
  1391.  
  1392. static ObjectAccessorCaller GetCallObjectAccessor()
  1393. {
  1394.     return CallObjectAccessor;
  1395. }
  1396.  
  1397. //------------------------------------------------------------------------------
  1398. // CallObjectAccessor
  1399. //------------------------------------------------------------------------------
  1400.  
  1401. static OSErr CallObjectAccessor(DescType        desiredClass,
  1402.                                     const OSLToken*    containerToken,
  1403.                                     DescType        containerClass,
  1404.                                     DescType        keyForm,
  1405.                                     const AEDesc*    keyData,
  1406.                                     OSLToken*        value,
  1407.                                     Boolean*        procFound,
  1408.                                     long            contextRefCon)
  1409. {
  1410.     OSErr                        error = noErr;
  1411.     TempODSemanticInterface        si = kODNULL;
  1412.     ODPart*                        thePart;
  1413.     Environment*                ev = somGetGlobalEnvironment();
  1414.     ODNameResolver*                nameResolver
  1415.         = ((SIContext*)contextRefCon)->GetNameResolver();
  1416.     ODFrame* const                kNoFrameInfo = kODNULL;
  1417.     ODBoolean                    allocatedContainerToken = kODFalse;
  1418.     
  1419.     *procFound = false;
  1420.  
  1421.     TRY
  1422.         si = GetSI(contextRefCon, &thePart);
  1423.     
  1424.         ODDesc* dataODDesc = new ODDesc();
  1425.         THROW_IF_NULL(dataODDesc);
  1426.         dataODDesc->InitODDesc(ev);
  1427.         THROW_IF_ERROR( AEDescToODDesc( (AEDesc*)keyData, dataODDesc ));
  1428.     
  1429.         // INITIALIZE TOKENS (OPTIMIZATION?: SHOULD ONLY DO THIS IF WE CAN
  1430.         //    ACTUALLY CALL AN OBJECT ACCESSOR.)
  1431.     
  1432.         ODOSLToken* containerODDesc = new ODOSLToken();
  1433.         THROW_IF_NULL(containerODDesc);
  1434.         containerODDesc->InitODOSLToken(ev);
  1435.         THROW_IF_ERROR(AEDescToODDesc((OSLToken*)containerToken,
  1436.                                         containerODDesc));
  1437.     
  1438.         ODOSLToken* valueWrapper = new ODOSLToken();
  1439.         THROW_IF_NULL(valueWrapper);
  1440.         valueWrapper->InitODOSLToken(ev);
  1441.     
  1442.         OSLContext context;
  1443.         GetCurrentContext(&context);
  1444.         ODFrame* frame = FrameFromContext(&context);
  1445.         ASSERT_FRAME_MATCHES_PART( ev, frame, thePart );
  1446.     
  1447.         if (!nameResolver->IsODToken(ev, valueWrapper))
  1448.             NewODToken( nameResolver, valueWrapper, thePart, frame, value);
  1449.     
  1450.         //  HANDLE NULL CONTAINER TOKEN.
  1451.         if (!nameResolver->IsODToken(ev, containerODDesc))
  1452.         {
  1453.             NewODToken(nameResolver, containerODDesc, thePart,
  1454.                         frame,  (AEDesc*)containerToken);
  1455.             allocatedContainerToken = kODTrue;
  1456.         }
  1457.     
  1458.         if ( si )
  1459.         {
  1460.             TRY
  1461.                 si->CallObjectAccessor(ev, thePart, (ODDescType)desiredClass,
  1462.                                     containerODDesc,
  1463.                                     (ODDescType)containerClass,
  1464.                                     (ODDescType)keyForm, dataODDesc,
  1465.                                     valueWrapper);
  1466.                 SetIsDefaultToken(nameResolver, valueWrapper, kODFalse);
  1467.             CATCH_ALL
  1468.                 error = ErrorCode();
  1469.             ENDTRY
  1470.         }
  1471.     
  1472.         if ( (error == errAEEventNotHandled || !si)
  1473.                 && TokenDefaultCanHandle( ev, nameResolver, containerODDesc) )
  1474.         {
  1475.             ODMessageInterface* msgintf =
  1476.                     nameResolver->GetSession(ev)->GetMessageInterface(ev);
  1477.             DefaultAccessorSI* defaultSI =
  1478.                     (DefaultAccessorSI*)msgintf->GetDefaultSI(ev);
  1479.             
  1480.             TRY
  1481.                 defaultSI->CallObjectAccessor(ev, thePart, desiredClass,
  1482.                         containerODDesc, containerClass, keyForm,
  1483.                         dataODDesc, valueWrapper);
  1484.                 SetIsDefaultToken(nameResolver, valueWrapper, kODTrue);
  1485.                 error = kODNoError;
  1486.             CATCH_ALL
  1487.                 error = ErrorCode();
  1488.             ENDTRY
  1489.         }
  1490.  
  1491.         // <eeh> part of memory leak fixing though I no longer remember
  1492.         // quite what leak....
  1493.  
  1494.         if ( error == noErr )
  1495.             THROW_IF_ERROR( ODDescToAEDesc(valueWrapper, value) );
  1496.  
  1497.         ODDeleteObject(valueWrapper);
  1498.         ODDeleteObject(dataODDesc);
  1499.         if (allocatedContainerToken)
  1500.         {
  1501.             ODDesc*     userToken = nameResolver->GetUserToken(ev, containerODDesc);
  1502.             DescType dt = nameResolver->GetUserToken(ev, containerODDesc)
  1503.                                             ->GetDescType(ev);
  1504.  
  1505.             // $$$$$ SHOULDN'T USE NEWODTOKEN FOR CONTAINERS. IT ALLOCATES
  1506.             //    A AEDESC WHEN WE DON'T NEED IT. HERE WE CHECK TO SEE IF IT DID
  1507.             //    THIS AND GET RID OF IT IF SO. FIX THIS!!!!!
  1508. //            if ( (dt == 'dead') || (dt == typeNull)
  1509. //                    || (dt == typeObjectBeingExamined) )
  1510.             if ( (dt == typeNull) || (dt == typeObjectBeingExamined) )
  1511.                 AEDisposeDesc((AEDesc*)containerToken);
  1512.  
  1513.             nameResolver->DisposeToken(ev, containerODDesc);
  1514.         }
  1515. #define FIX_FOR_EVERY_LEAK 1
  1516. #if FIX_FOR_EVERY_LEAK
  1517.         else
  1518.             ODDeleteObject(containerODDesc);
  1519. #endif
  1520.     CATCH_ALL
  1521.         error = ErrorCode();
  1522.     ENDTRY
  1523.  
  1524.     return error;
  1525. }
  1526.  
  1527. //------------------------------------------------------------------------------
  1528. // GetGetAppDoesFlags
  1529. //
  1530. //    Used for compile-time type checking only.
  1531. //------------------------------------------------------------------------------
  1532.  
  1533. static CallbackFlagsGetter GetGetAppDoesFlags()
  1534. {
  1535.     return GetAppDoesFlags;
  1536. }
  1537.  
  1538. //------------------------------------------------------------------------------
  1539. // GetAppDoesFlags
  1540. //------------------------------------------------------------------------------
  1541.  
  1542. static long GetAppDoesFlags(long contextRefCon)
  1543. {
  1544.     ODPart*                    thePart;
  1545.     TempODSemanticInterface    si = GetSI(contextRefCon, &thePart);
  1546.     
  1547.     if( !si )
  1548.         return kAEIDoMinimum;
  1549.     else
  1550.     {
  1551.         Environment* ev = somGetGlobalEnvironment();
  1552.         long result = si->GetOSLSupportFlags(ev);
  1553.         return result;
  1554.     }
  1555. }
  1556.  
  1557. //------------------------------------------------------------------------------
  1558. // GetSpecialProc
  1559. //
  1560. //    Lookup special proc given a context. Return kODFalse if not found, kODTrue
  1561. //    otherwise.
  1562. //------------------------------------------------------------------------------
  1563. #if 0
  1564. static ODBoolean GetSpecialProc(long                            contextRefCon,
  1565.                                     ODSemanticInterface*&        si,
  1566.                                     ODPart*&                    thePart)
  1567. {
  1568.     si = GetSI(contextRefCon, &si, &thePart);
  1569.     if( !si )
  1570.         return kODFalse;
  1571.  
  1572. //    theSI->GetSpecialHandler(funcType, &proc, &refCon);
  1573.  
  1574. //    if (!proc)
  1575. //        return kODFalse;
  1576.     
  1577.     return kODTrue;
  1578. }
  1579. #endif
  1580. //------------------------------------------------------------------------------
  1581. // CallCountProcAux
  1582. //------------------------------------------------------------------------------
  1583.  
  1584. static void CallCountProcAux(DescType            desiredClass,
  1585.                                 DescType        containerClass,
  1586.                                 const OSLToken*    container,
  1587.                                 long*            result,
  1588.                                 long            contextRefCon,
  1589.                                 ODOSLToken*        containerWrapper)
  1590. {
  1591.     ODPart*                        thePart;
  1592.     Environment*                ev = somGetGlobalEnvironment();
  1593.     OSErr                        error = noErr;
  1594.     ODOSLToken*                    newContainerWrapper = kODNULL;
  1595.     ODNameResolver*                nameResolver
  1596.         = ((SIContext*)contextRefCon)->GetNameResolver();
  1597.  
  1598.     {
  1599.         TempODSemanticInterface si = GetSI(contextRefCon, &thePart);
  1600.     
  1601.         // TRY WITH THE PART'S SI FIRST
  1602.         if (si)
  1603.         {
  1604.             TRY
  1605.                 si->CallCountProc(ev, thePart, desiredClass, containerClass,
  1606.                                         containerWrapper, (ODSLong*)result);
  1607.             CATCH_ALL
  1608.                 error = ErrorCode();
  1609.             ENDTRY
  1610.         } else
  1611.             error = errAEEventNotHandled;
  1612.     }
  1613.  
  1614.     // SOME ERROR OCCURRED. TRY DEFAULT SI
  1615.     if (error == errAEEventNotHandled
  1616.             && TokenDefaultCanHandle( ev, nameResolver, containerWrapper))
  1617.     {
  1618.         TRY
  1619.             ODMessageInterface* msgintf =
  1620.                     nameResolver->GetSession(ev)->GetMessageInterface(ev);
  1621.             DefaultAccessorSI* defaultSI =
  1622.                     (DefaultAccessorSI*)msgintf->GetDefaultSI(ev);
  1623.     
  1624.             defaultSI->CallCountProc(ev, thePart, desiredClass,
  1625.                                         containerClass, containerWrapper,
  1626.                                         (ODSLong*)result);
  1627.             error = noErr;
  1628.         CATCH_ALL
  1629.             error = ErrorCode();
  1630.         ENDTRY
  1631.         
  1632.         THROW_IF_ERROR( error );
  1633.     }
  1634. }
  1635.  
  1636. //------------------------------------------------------------------------------
  1637. // GetCallCountProc
  1638. //
  1639. //    Used for compile-time type checking only.
  1640. //------------------------------------------------------------------------------
  1641.  
  1642. static CountProcCaller GetCallCountProc()
  1643. {
  1644.     return CallCountProc;
  1645. }
  1646.  
  1647. //------------------------------------------------------------------------------
  1648. // CallCountProc
  1649. //------------------------------------------------------------------------------
  1650.  
  1651. static OSErr CallCountProc(DescType            desiredClass,
  1652.                                 DescType        containerClass,
  1653.                                 const OSLToken*    container,
  1654.                                 long*            result,
  1655.                                 long            contextRefCon)
  1656. {
  1657.     Environment*                ev = somGetGlobalEnvironment();
  1658.     OSErr                        error = noErr;
  1659.     ODOSLToken*                    newContainerWrapper = kODNULL;
  1660.     ODDesc*                        userToken = kODNULL;
  1661.     AEDesc                        userTokenAsAEDesc;
  1662.     OSLContext                    savedCurContext;
  1663.     OSLContext                    newContext;
  1664.     ODFrame*                    theFrame;
  1665.     ODNameResolver*                nameResolver
  1666.         = ((SIContext*)contextRefCon)->GetNameResolver();
  1667.     ODBoolean                    allocatedContainerToken = kODFalse;
  1668.  
  1669.     TRY
  1670.         // SET UP ODDESC FOR CONTAINER
  1671.         ODOSLToken* containerWrapper = new ODOSLToken();
  1672.         THROW_IF_NULL(containerWrapper);
  1673.         containerWrapper->InitODOSLToken(ev);
  1674.         THROW_IF_ERROR(AEDescToODDesc((AEDesc*)container, containerWrapper));
  1675.  
  1676.         // INITIALIZE CONTAINER TOKEN TO OPENDOC TOKEN
  1677.         //    GET USER TOKEN SO THAT WE CAN LOOK AT IT
  1678.         //    WE ASSUME HERE THAT ONLY TIME THIS CAN HAPPEN IN WHEN THE SHELL IS
  1679.         //    INVOLVED.
  1680.         if (!nameResolver->IsODToken(ev, containerWrapper))
  1681.         {
  1682.             NewODToken(nameResolver, containerWrapper, kODAppShell, kODNULL,
  1683.                         (OSLToken*)container);
  1684.             allocatedContainerToken = kODTrue;
  1685.             MakeNULLToken(&userTokenAsAEDesc); // container?
  1686.         }
  1687.         else
  1688.         {
  1689.             userToken = nameResolver->GetUserToken(ev, containerWrapper);
  1690.             THROW_IF_ERROR(ODDescToAEDesc(userToken, &userTokenAsAEDesc));
  1691.         }
  1692.  
  1693.         TRY
  1694.             CallCountProcAux(desiredClass, containerClass, container, result,
  1695.                                 contextRefCon, containerWrapper);
  1696.         CATCH_ALL
  1697.             error = ErrorCode();
  1698.         ENDTRY
  1699.  
  1700.         // TRY SWAPPING TO EMBEDDED FRAME IF THE PART RETURNS THE SPECIAL
  1701.         //    "SWAP" RESULT.
  1702.  
  1703.         // NORMALLY, WE SHOULD ONLY ALLOW SWAPPING IF THE CONTAINER IS A
  1704.         //    STANDARD PART TOKEN. HOWEVER, WHEN thePart IS kODNULL, THEN WE
  1705.         //    KNOW THAT THE APPLICATION IS THE CONTAINER AND THE REQUEST TO
  1706.         //    SWAP SHOULD BE TRANSLATED INTO A SWAP TO THE ROOT PART.
  1707.         
  1708.         // IS THERE ANOTHER CASE WE HAVE TO WORRY ABOUT?
  1709.         
  1710.         if (*result == kODCountProcSwapValue && error == noErr)
  1711.         {
  1712.             ODPart* thePart = kODNULL;
  1713.             if ( CanBeStandardPartToken( &userTokenAsAEDesc ) )
  1714.             {
  1715.                 PartFrameFromStandardPartToken( &userTokenAsAEDesc, &thePart,
  1716.                         &theFrame );
  1717.                 thePart->Acquire(ev);
  1718.             }
  1719.             else
  1720.             {
  1721.                 theFrame = GetDefaultRootFrameToSwapTo(ev,
  1722.                                             nameResolver->GetSession(ev));
  1723.                 thePart = theFrame->AcquirePart(ev);
  1724.             }
  1725.             
  1726.             { TempODPart tempPart = thePart; // ensure it's released
  1727.  
  1728.               THROW_IF_ERROR(GetCurrentContext(&savedCurContext));
  1729.             
  1730.               nameResolver->GetContextForPart(ev, thePart, theFrame,
  1731.                                             &newContext);
  1732.             }
  1733.             
  1734.             THROW_IF_ERROR(SetCurrentContext(&newContext));
  1735.             
  1736.             TRY
  1737.                 // SET UP A NULL CONTAINER.
  1738.  
  1739.                 // SET THE USER TOKEN TO NULL AND SET THE CONTEXT OF THE
  1740.                 //    TOKEN TO THE RIGHT THING.
  1741.  
  1742.                 ODDesc*    tempODDesc = new ODDesc();
  1743.                 THROW_IF_NULL(tempODDesc);
  1744.                 tempODDesc->InitODDesc(ev);
  1745.  
  1746. #define FIX_FOR_WHOSE_LEAK 1
  1747. #if FIX_FOR_WHOSE_LEAK
  1748.                 // SAVE OLD CONTAINER ODOSLTOKEN
  1749.                 ODOSLToken*    oldContainerWrapper = containerWrapper;
  1750.  
  1751.                 containerWrapper = new ODOSLToken();
  1752.                 THROW_IF_NULL(containerWrapper);
  1753.                 containerWrapper->InitODOSLToken(ev);
  1754. #endif
  1755.  
  1756.                 SetUserODToken((OSLToken*)container, tempODDesc);
  1757.                 OSLSetTokenContext((OSLToken*)container, &newContext);
  1758.                 THROW_IF_ERROR( AEDescToODDesc( (AEDesc*)container, containerWrapper ) );
  1759.  
  1760.                 // RESET CONTAINER CLASS
  1761.                 containerClass = typeNull;
  1762.  
  1763.                 TRY
  1764.                     CallCountProcAux(desiredClass, containerClass, container,
  1765.                                     result, newContext.refCon,
  1766.                                     containerWrapper);
  1767.                 CATCH_ALL
  1768.                     error = ErrorCode();
  1769.                 ENDTRY
  1770.                 // RESTORE PREVIOUS USER TOKEN.  Restore even in case
  1771.                 // of error so dispose will Release Frame and Part (for
  1772.                 // the common case where we tried swapping to a StdPartToken.
  1773.                 
  1774. #if FIX_FOR_WHOSE_LEAK
  1775.                 nameResolver->DisposeToken(ev, containerWrapper);
  1776.                 containerWrapper = oldContainerWrapper;
  1777. #endif
  1778.                 
  1779.                 SetUserODToken((OSLToken*)container, userToken);
  1780.                 THROW_IF_ERROR(error);
  1781.                 if ( *result == kODCountProcSwapValue )
  1782.                     THROW( errAEEventNotHandled );
  1783.             CATCH_ALL
  1784.                 THROW_IF_ERROR(SetCurrentContext(&savedCurContext));
  1785.                 RERAISE;
  1786.             ENDTRY
  1787.             
  1788.             THROW_IF_ERROR(SetCurrentContext(&savedCurContext));
  1789.         }
  1790.  
  1791.         if (allocatedContainerToken)
  1792.             nameResolver->DisposeToken(ev, containerWrapper);
  1793.     CATCH_ALL
  1794.         error = ErrorCode();
  1795.     ENDTRY
  1796.  
  1797.     (void)AEDisposeDesc( &userTokenAsAEDesc );
  1798.     return error;
  1799. }
  1800.  
  1801. //------------------------------------------------------------------------------
  1802. // GetCallCompareProc
  1803. //
  1804. //    Used for compile-time type checking only.
  1805. //------------------------------------------------------------------------------
  1806.  
  1807. static CompareProcCaller GetCallCompareProc()
  1808. {
  1809.     return CallCompareProc;
  1810. }
  1811.  
  1812. //------------------------------------------------------------------------------
  1813. // CallCompareProc
  1814. //------------------------------------------------------------------------------
  1815.  
  1816. static ODOSLToken* MakeODOSLToken( Environment* ev, ODNameResolver* nameResolver,
  1817.         ODPart* part, ODFrame* frame, const AEDesc* desc );
  1818. static ODOSLToken* MakeODOSLToken( Environment* ev, ODNameResolver* nameResolver,
  1819.         ODPart* part, ODFrame* frame, const AEDesc* desc )
  1820. {
  1821.     ODOSLToken* result = new ODOSLToken();
  1822.     THROW_IF_NULL(result);
  1823.     result->InitODOSLToken(ev);
  1824.  
  1825.     if ( noErr == AEDescToODDesc( (OSLToken*)desc, result ) )
  1826.     {
  1827.         return result;
  1828.     }
  1829.     else
  1830.     {
  1831.         ODDeleteObject(result);
  1832.         return kODNULL;
  1833.     }
  1834. }
  1835.  
  1836. static OSErr CallCompareProc(DescType            oper,
  1837.                                 const OSLToken*    obj1,
  1838.                                 const OSLToken*    obj2,
  1839.                                 ODBoolean*        result,
  1840.                                 long            contextRefCon)
  1841. {
  1842.     OSErr                        error = noErr;
  1843.     TempODSemanticInterface        si = kODNULL;
  1844.     Environment*                ev = somGetGlobalEnvironment();
  1845.     ODPart*                        thePart;
  1846.     ODOSLToken* tokenWrapper1 = kODNULL;    ODVolatile(tokenWrapper1);
  1847.     ODOSLToken* tokenWrapper2 = kODNULL;    ODVolatile(tokenWrapper2);
  1848.     ODNameResolver*                nameResolver
  1849.         = ((SIContext*)contextRefCon)->GetNameResolver();
  1850.  
  1851.     TRY
  1852.         si = GetSI( contextRefCon, &thePart );
  1853.         ODFrame* frame = ((SIContext*)contextRefCon)->GetFrame();
  1854.         tokenWrapper1 = MakeODOSLToken( ev, nameResolver, thePart, frame, obj1 );
  1855.         tokenWrapper2 = MakeODOSLToken( ev, nameResolver, thePart, frame, obj2 );
  1856.     CATCH_ALL
  1857.         error = ErrorCode();
  1858.     ENDTRY
  1859.  
  1860.     if ( !error )
  1861.     {
  1862.         if ( si )
  1863.         {
  1864.             TRY
  1865.                 si->CallCompareProc( ev, thePart, oper, tokenWrapper1,
  1866.                                         tokenWrapper2, result );
  1867.             CATCH_ALL
  1868.                 error = ErrorCode();
  1869.             ENDTRY
  1870.         }
  1871.         
  1872.         // don't touch the error code already returned.  Return it if the
  1873.         // defaults fail.
  1874.         if ( !si || error == errAEEventNotHandled )
  1875.                     // <eeh> what value means failed to compare?
  1876.         {
  1877.             TRY
  1878.                 ODMessageInterface* msgintf =
  1879.                         nameResolver->GetSession(ev)->GetMessageInterface(ev);
  1880.                 DefaultAccessorSI* defaultSI =
  1881.                         (DefaultAccessorSI*)msgintf->GetDefaultSI(ev);
  1882.                 defaultSI->CallCompareProc( ev, thePart, oper, tokenWrapper1,
  1883.                                         tokenWrapper2, result );
  1884.                 // If we got here, there was no error.
  1885.                 error = noErr;
  1886.             CATCH_ALL
  1887.                 error = ErrorCode();
  1888.             ENDTRY
  1889.         }
  1890.     }
  1891.  
  1892.     ODDeleteObject(tokenWrapper1);
  1893.     ODDeleteObject(tokenWrapper2);
  1894.     return error;
  1895. }
  1896.  
  1897. //------------------------------------------------------------------------------
  1898. // GetCallDisposeTokenProc
  1899. //
  1900. //    Used for compile-time type checking only.
  1901. //------------------------------------------------------------------------------
  1902.  
  1903. static DisposeTokenProcCaller GetCallDisposeTokenProc()
  1904. {
  1905.     return CallDisposeTokenProc;
  1906. }
  1907.  
  1908. //------------------------------------------------------------------------------
  1909. // CallDisposeTokenProc
  1910. //------------------------------------------------------------------------------
  1911.  
  1912. static OSErr CallDisposeTokenProc(OSLToken*    unneededToken,
  1913.                                     long        contextRefCon)
  1914. {
  1915.     TempODSemanticInterface        si = kODNULL;
  1916.     ODPart*                        thePart;
  1917.     Environment*                ev = somGetGlobalEnvironment();
  1918.     OSErr                        error = noErr;
  1919.     ODNameResolver*                nameResolver
  1920.         = ((SIContext*)contextRefCon)->GetNameResolver();
  1921.     ODOSLToken*                    tokenWrapper = kODNULL;        ODVolatile(tokenWrapper);
  1922.  
  1923.     TRY
  1924.         TRY
  1925.             si = GetSI( contextRefCon, &thePart );
  1926.             tokenWrapper = new ODOSLToken();
  1927.             THROW_IF_NULL(tokenWrapper);
  1928.             tokenWrapper->InitODOSLToken(ev);
  1929.             THROW_IF_ERROR( AEDescToODDesc( unneededToken, tokenWrapper ) );
  1930.         CATCH_ALL
  1931.             error = ErrorCode();
  1932.         ENDTRY
  1933.     
  1934.         if ( !error )
  1935.         {
  1936.             ODDesc*    userToken = kODNULL;
  1937.  
  1938.             // GET A REFERENCE TO THE USER TOKEN (IF ANY) HERE, SO THAT WE STILL
  1939.             //    HAVE A VALID REFERENCE TO IT IF THE USER'S DISPOSETOKEN PROC
  1940.             //    DEALLOCATES THE ODOSLToken.
  1941.             if (nameResolver->IsODToken(ev, tokenWrapper)
  1942.                     || (unneededToken->descriptorType == kSwitchDescType))
  1943.                 userToken = GetUserODToken(unneededToken);
  1944.  
  1945.             TRY
  1946.                 if ( si )
  1947.                     si->CallDisposeTokenProc(ev, thePart, tokenWrapper);
  1948.             CATCH_ALL
  1949.                 error = ErrorCode();
  1950.             ENDTRY
  1951.         
  1952.             if ( !si || (error == errAEEventNotHandled) )
  1953.             {
  1954.                 TRY
  1955.                     ODMessageInterface* msgintf =
  1956.                             nameResolver->GetSession(ev)->GetMessageInterface(ev);
  1957.                     DefaultAccessorSI* defaultSI =
  1958.                             (DefaultAccessorSI*)msgintf->GetDefaultSI(ev);
  1959.                     defaultSI->CallDisposeTokenProc(ev, thePart, tokenWrapper);
  1960.                 CATCH_ALL
  1961.                     error = ErrorCode();
  1962.                 ENDTRY
  1963.             }
  1964.     
  1965.             // ALWAYS DELETE THE USER TOKEN
  1966.             if (userToken)
  1967.                 delete userToken;
  1968.             
  1969.             // ONLY DELETE THE TOKEN ITSELF IF NO ONE ELSE HANDLED IT.
  1970.             if (error)
  1971.             {
  1972.     //            WARN("No dispose token proc handled it. NameResolver handling.");
  1973.                 ODDeleteObject(tokenWrapper);
  1974.             }
  1975.         }
  1976.     CATCH_ALL
  1977.         error = ErrorCode();
  1978.     ENDTRY
  1979.  
  1980.     // IF THERE WAS NO ERROR, MAKE SURE WE DISPOSE THE AEDESC, BUT THE OSL
  1981.     //    WON'T. IT WILL IF WE RETURN AN ERROR.
  1982.     if (error == kODNoError)
  1983.         AEDisposeDesc(unneededToken);
  1984.  
  1985.     return error;
  1986. }
  1987.  
  1988. //------------------------------------------------------------------------------
  1989. // GetMarkProc
  1990. //
  1991. //    Used for compile-time type checking only.
  1992. //------------------------------------------------------------------------------
  1993.  
  1994. static MarkProcCaller GetMarkProc()
  1995. {
  1996.     return CallMarkProc;
  1997. }
  1998.  
  1999. //------------------------------------------------------------------------------
  2000. // CallMarkProc
  2001. //------------------------------------------------------------------------------
  2002.  
  2003. static OSErr CallMarkProc(const OSLToken*    dToken,
  2004.                             const OSLToken*    markToken,
  2005.                             long            index,
  2006.                             long            contextRefCon)
  2007. {
  2008.     OSErr                        error = noErr;
  2009.     Environment*                ev = somGetGlobalEnvironment();
  2010.     ODPart*                        thePart;
  2011.     ODNameResolver*                nameResolver
  2012.         = ((SIContext*)contextRefCon)->GetNameResolver();
  2013.  
  2014.     TempODSemanticInterface si = GetSI(contextRefCon, &thePart);
  2015.     if( !si )
  2016.         return errAENotASpecialFunction;
  2017.  
  2018.     ODOSLToken* tokenWrapper = kODNULL;            ODVolatile(tokenWrapper);
  2019.     ODOSLToken* markTokenWrapper = kODNULL;        ODVolatile(markTokenWrapper);
  2020.     TRY
  2021.         tokenWrapper = new ODOSLToken();
  2022.         THROW_IF_NULL(tokenWrapper);
  2023.         tokenWrapper->InitODOSLToken(ev);
  2024.         THROW_IF_ERROR( AEDescToODDesc( (OSLToken*)dToken, tokenWrapper ) );
  2025.  
  2026.         markTokenWrapper = new ODOSLToken();
  2027.         THROW_IF_NULL(markTokenWrapper);
  2028.         markTokenWrapper->InitODOSLToken(ev);
  2029.         THROW_IF_ERROR(AEDescToODDesc( (OSLToken*)markToken, markTokenWrapper));
  2030.         si->CallMarkProc(ev, thePart, tokenWrapper,
  2031.                                 markTokenWrapper, index);
  2032.     CATCH_ALL
  2033.         error = ErrorCode();
  2034.     ENDTRY
  2035.     
  2036.     ODDeleteObject(tokenWrapper);
  2037.     ODDeleteObject(markTokenWrapper);
  2038.     return error;
  2039. }
  2040.  
  2041. //------------------------------------------------------------------------------
  2042. // GetMarkTokenProc
  2043. //
  2044. //    Used for compile-time type checking only.
  2045. //------------------------------------------------------------------------------
  2046.  
  2047. static GetMarkTokenProcCaller GetMarkTokenProc()
  2048. {
  2049.     return CallGetMarkTokenProc;
  2050. }
  2051.  
  2052. //------------------------------------------------------------------------------
  2053. // CallGetMarkTokenProc
  2054. //------------------------------------------------------------------------------
  2055.  
  2056. static OSErr CallGetMarkTokenProc(const OSLToken*    dContainerToken,
  2057.                                     DescType        containerClass,
  2058.                                     OSLToken*        result,
  2059.                                     long            contextRefCon)
  2060. {
  2061.     OSErr                    error = noErr;
  2062.     Environment*                ev = somGetGlobalEnvironment();
  2063.     ODPart*                thePart;
  2064.     ODNameResolver*                nameResolver
  2065.         = ((SIContext*)contextRefCon)->GetNameResolver();
  2066.  
  2067.     TempODSemanticInterface si = GetSI(contextRefCon, &thePart);
  2068.     if( !si )
  2069.         return errAENotASpecialFunction;
  2070.  
  2071.     ODOSLToken* tokenWrapper = kODNULL;        ODVolatile(tokenWrapper);
  2072.     TRY
  2073.         tokenWrapper = new ODOSLToken();
  2074.         THROW_IF_NULL(tokenWrapper);
  2075.         tokenWrapper->InitODOSLToken(ev);
  2076.         THROW_IF_ERROR( AEDescToODDesc( (OSLToken*)dContainerToken, tokenWrapper ) );
  2077.  
  2078.         ODOSLToken* resultWrapper = new ODOSLToken();
  2079.         THROW_IF_NULL(resultWrapper);
  2080.         resultWrapper->InitODOSLToken(ev);
  2081.         si->CallGetMarkTokenProc(ev, thePart, tokenWrapper,
  2082.                                                 containerClass,
  2083.                                                 resultWrapper);
  2084.         THROW_IF_ERROR( ODDescToAEDesc(resultWrapper, result));
  2085.         ODDeleteObject(resultWrapper);
  2086.     CATCH_ALL
  2087.         error = ErrorCode();
  2088.     ENDTRY
  2089.     
  2090.     ODDeleteObject(tokenWrapper);
  2091.     return error;
  2092. }
  2093.  
  2094. //------------------------------------------------------------------------------
  2095. // GetAdjustMarksProc
  2096. //
  2097. //    Used for compile-time type checking only.
  2098. //------------------------------------------------------------------------------
  2099.  
  2100. static AdjustMarksProcCaller GetAdjustMarksProc()
  2101. {
  2102.     return CallAdjustMarksProc;
  2103. }
  2104.  
  2105. //------------------------------------------------------------------------------
  2106. // CallAdjustMarksProc
  2107. //------------------------------------------------------------------------------
  2108.  
  2109. static OSErr CallAdjustMarksProc(long                newStart,
  2110.                                     long            newStop,
  2111.                                     const OSLToken*    markToken,
  2112.                                     long            contextRefCon)
  2113. {
  2114.     OSErr                    error = noErr;
  2115.     Environment*                ev = somGetGlobalEnvironment();
  2116.     ODPart*                thePart;
  2117.  
  2118.     TempODSemanticInterface si = GetSI(contextRefCon, &thePart);
  2119.     if (!si)
  2120.         return errAENotASpecialFunction;
  2121.  
  2122.     ODOSLToken* tokenWrapper = kODNULL;        ODVolatile(tokenWrapper);
  2123.     TRY
  2124.         tokenWrapper = new ODOSLToken();
  2125.         THROW_IF_NULL(tokenWrapper);
  2126.         tokenWrapper->InitODOSLToken(ev);
  2127.         THROW_IF_ERROR( AEDescToODDesc( (OSLToken*)markToken, tokenWrapper ) );
  2128.  
  2129.         si->CallAdjustMarksProc(ev, thePart, newStart, newStop,
  2130.                                                     tokenWrapper);
  2131.     CATCH_ALL
  2132.         error = ErrorCode();
  2133.     ENDTRY
  2134.     
  2135.     ODDeleteObject(tokenWrapper);
  2136.     return error;
  2137. }
  2138.  
  2139. //------------------------------------------------------------------------------
  2140. // GetGetErrDescProc
  2141. //
  2142. //    Used for compile-time type checking only.
  2143. //------------------------------------------------------------------------------
  2144.  
  2145. static GetErrDescProcCaller GetGetErrDescProc()
  2146. {
  2147.     return CallGetErrDescProc;
  2148. }
  2149.  
  2150. //------------------------------------------------------------------------------
  2151. // CallGetErrDescProc
  2152. //------------------------------------------------------------------------------
  2153.  
  2154. static OSErr CallGetErrDescProc(AEDesc**    appDescPtr,
  2155.                                     long    contextRefCon)
  2156. {
  2157.     TempODSemanticInterface        si = kODNULL;
  2158.     ODPart*                        thePart;
  2159.     Environment*                ev = somGetGlobalEnvironment();
  2160.     OSErr                        error = noErr;
  2161.     ODNameResolver*                nameResolver
  2162.         = ((SIContext*)contextRefCon)->GetNameResolver();
  2163.  
  2164.     si = GetSI(contextRefCon, &thePart);
  2165.     if (!si)
  2166.         return errAENotASpecialFunction;
  2167.  
  2168.     TRY
  2169.         ODDesc*    errorODDesc;
  2170.         si->CallGetErrDescProc(ev, thePart, &errorODDesc);
  2171.         *appDescPtr = nameResolver->AddErrDescToList(ev, errorODDesc);
  2172.     CATCH_ALL
  2173.         error = ErrorCode();
  2174.     ENDTRY
  2175.     return error;
  2176. }
  2177.  
  2178.